﻿@using Flagrum.Web.Persistence.Entities
@using Index = Flagrum.Web.Features.AssetExplorer.Index
@using Flagrum.Web.Features.AssetExplorer.Data
@using System.IO
@using System.Text
@using Flagrum.Core.Animation
@using Flagrum.Core.Archive
@using Flagrum.Core.Ebex.Xmb2
@using Flagrum.Core.Gfxbin.Btex
@using Flagrum.Core.Utilities.Types
@using Flagrum.Web.Features.AssetExplorer.Base
@using Flagrum.Web.Features.Settings.Data
@inject IWpfService WpfService
@inject FlagrumDbContext Context
@inject ILogger<ExportContextMenu> Logger
@inject EnvironmentPacker EnvironmentPacker
@inject TerrainPacker TerrainPacker
@inject IStringLocalizer<ExportContextMenu> Localizer
@inject AppStateService AppState
@inject ProfileService Profile

<ContextMenu Id="assetExplorerMenu"
             OverrideDefaultCssClass="fixed select-none bg-grey-700 p-0 border-0 shadow-md"
             OverrideDefaultListCssClass="p-0"
             OnAppearing="OnAppearing"
             OnHiding="OnHiding"
             @ref="ContextMenu">
    @if (AssetExplorer.ContextNode?.Type == ExplorerItemType.Directory)
    {
        <Item OnClick="ExportFolder"
              OverrideDefaultCssClass="text-grey-200 text-sm p-3 hover:bg-grey-600 cursor-pointer transition-colors">
            <div class="row">
                <span class="material-icons mr-3" style="font-size: 0.9rem">drive_file_move</span>
                <span>@(Parent.CurrentView == AssetExplorerView.GameView ? Localizer["ExportFolder"] : Localizer["ConvertFolder"])</span>
            </div>
        </Item>
    }
    else
    {
        <Item OnClick="ExportSingle"
              OverrideDefaultCssClass="text-grey-200 text-sm p-3 hover:bg-grey-600 cursor-pointer transition-colors">
            <div class="row">
                <span class="material-icons mr-3" style="font-size: 0.9rem">open_in_new</span>
                <span>@Localizer["ExportFile"]</span>
            </div>
        </Item>

        switch (AssetExplorer.ContextNode?.Type)
        {
            case ExplorerItemType.Model:
                if (Parent.CurrentView == AssetExplorerView.GameView)
                {
                    <Item OnClick="() => ExportWithDependenciesModal.Open(AssetExplorer.ContextNode)"
                          OverrideDefaultCssClass="text-grey-200 text-sm p-3 hover:bg-grey-600 cursor-pointer transition-colors">
                        <div class="row">
                            <span class="material-icons mr-3" style="font-size: 0.9rem">share</span>
                            <span>@Localizer["ExportWithDependencies"]</span>
                        </div>
                    </Item>
                }
                break;
            case ExplorerItemType.Xml:
                if (Profile.Current.Type == LuminousGame.FFXV && Parent.CurrentView == AssetExplorerView.GameView)
                {
                    <Item OnClick="@ExportEnvironment"
                          OverrideDefaultCssClass="text-grey-200 text-sm p-3 hover:bg-grey-600 cursor-pointer transition-colors">
                        <div class="row">
                            <span class="material-icons mr-3" style="font-size: 0.9rem">public</span>
                            <span>@Localizer["ExportAsEnvironment"]</span>
                        </div>
                    </Item>
                    <Item OnClick="@ExportTerrain"
                          OverrideDefaultCssClass="text-grey-200 text-sm p-3 hover:bg-grey-600 cursor-pointer transition-colors">
                        <div class="row">
                            <span class="material-icons mr-3" style="font-size: 0.9rem">grass</span>
                            <span>@Localizer["ExportAsTerrain"]</span>
                        </div>
                    </Item>
                }
                break;
            case ExplorerItemType.AnimationPackage:
                <Item OnClick="@ExportAnimationClips"
                      OverrideDefaultCssClass="text-grey-200 text-sm p-3 hover:bg-grey-600 cursor-pointer transition-colors">
                    <div class="row">
                        <span class="material-icons mr-3" style="font-size: 0.9rem">widgets</span>
                        <span>@Localizer["ExportAnimationClips"]</span>
                    </div>
                </Item>
                break;
        }
    }
</ContextMenu>

<ExportWithDependenciesModal @ref="ExportWithDependenciesModal"/>
<ExportFolderModal @ref="ExportFolderModal"/>

@code
{
    [CascadingParameter(Name = "AssetExplorer")]
    public AssetExplorer AssetExplorer { get; set; }
    
    [CascadingParameter]
    public IAssetExplorerParent Parent { get; set; }

    private ContextMenu ContextMenu { get; set; }
    private ExportWithDependenciesModal ExportWithDependenciesModal { get; set; }
    private ExportFolderModal ExportFolderModal { get; set; }

    public void ExportCurrentFolder()
    {
        ExportFolderModal.SetContextNode(AssetExplorer.FileList.CurrentNode);
        ExportFolderModal.Open();
    }
    
    private void ExportFolder()
    {
        ExportFolderModal.SetContextNode(AssetExplorer.ContextNode);
        ExportFolderModal.Open();
    }

    private async Task ExportSingle()
    {
        var item = AssetExplorer.ContextNode;

        var filter = item.Type switch
        {
            ExplorerItemType.Material => "Game Material|*.gmtl.gfxbin",
            ExplorerItemType.Model => "Game Model|*.gmdl.gfxbin",
            ExplorerItemType.Texture => "PNG Image|*.png|TGA Image|*.tga|DDS Image|*.dds|BTEX Image|*.btex",
            ExplorerItemType.Xml => "eXtensible Markup Language|*.xml|Ebony XML (XMB2)|*.exml",
            _ => $"Unknown File|*.{UriHelper.GetTrueExtensionFromFileName(item.Name)}"
        };

        var trueExtension = UriHelper.GetTrueExtensionFromFileName(item.Name);
        await WpfService.OpenSaveFileDialogAsync(UriHelper.RemoveExtensionFromFileName(item.Name), filter, path =>
        {
            byte[] data;
            
            switch (item.Type)
            {
                case ExplorerItemType.Texture:
                {
                    var extension = path.Split('.').Last();
                    var converter = new TextureConverter(Profile.Current.Type);
                    converter.ExportTexture(path, (ImageFormat)extension, item.Data);
                    return;
                }
                case ExplorerItemType.Xml:
                {
                    var extension = path.Split('.').Last();
                    if (extension == "xml")
                    {
                        var builder = new StringBuilder();
                        Xmb2Document.Dump(item.Data, builder);
                        data = Encoding.UTF8.GetBytes(builder.ToString());
                    }
                    else
                    {
                        data = item.Data;
                    }
                    break;
                }
                case ExplorerItemType.Unspecified:
                case ExplorerItemType.Unsupported:
                case ExplorerItemType.Directory:
                case ExplorerItemType.Material:
                case ExplorerItemType.Model:
                case ExplorerItemType.Text:
                case ExplorerItemType.AnimationPackage:
                default:
                    path = path.Replace("." + trueExtension, "");
                    path += "." + trueExtension;
                    data = item.Data;
                    break;
            }

            File.WriteAllBytes(path, data);
        });
    }

    private async Task ExportEnvironment()
    {
        var item = AssetExplorer.ContextNode;
        const string filter = "Flagrum Environment Data|*.fed";

        await WpfService.OpenSaveFileDialogAsync(item.Name[..item.Name.LastIndexOf('.')] + ".fed", filter, async path =>
        {
            await InvokeAsync(() => AssetExplorer.SetLoading(true, "Exporting"));

            await Task.Run(() => { EnvironmentPacker.Pack(item.Path, path); });

            await InvokeAsync(() =>
            {
                AssetExplorer.SetLoading(false);
                WpfService.ShowWindowsNotification("Environment Export Complete");
            });
        });
    }

    private async Task ExportTerrain()
    {
        var item = AssetExplorer.ContextNode;
        const string filter = "Flagrum Terrain Data|*.ftd";

        await WpfService.OpenSaveFileDialogAsync(item.Name[..item.Name.LastIndexOf('.')] + ".ftd", filter, async path =>
        {
            await InvokeAsync(() => AssetExplorer.SetLoading(true, "Exporting"));
            await Task.Run(() => { TerrainPacker.Pack(item.Path, path); });
            await InvokeAsync(() => AssetExplorer.SetLoading(false));
        });
    }

    private async Task ExportAnimationClips()
    {
        var item = AssetExplorer.ContextNode;
        await WpfService.OpenFolderDialogAsync(Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
            async folderPath =>
            {
                await InvokeAsync(() => AssetExplorer.SetLoading(true, "Exporting"));
                var data = Context.GetFileByUri(item.Path);
                var package = AnimationPackage.FromData(data);
                foreach (var animation in package.Items)
                {
                    await File.WriteAllBytesAsync($@"{folderPath}\{package.Items.IndexOf(animation)}.ani", animation.Ani);
                }
                await InvokeAsync(() => AssetExplorer.SetLoading(false));
            });
    }

    private void OnAppearing()
    {
        if (AppState.Is3DViewerOpen)
        {
            WpfService.Set3DViewportVisibility(false);
        }
    }

    private void OnHiding()
    {
        AssetExplorer.ContextNode = null; 
        AssetExplorer.CallStateHasChanged();

        if (AppState.Is3DViewerOpen && !AppState.IsModalOpen)
        {
            WpfService.Set3DViewportVisibility(true);
        }
    }
}